<template>
  <a-modal
    :title="title"
    :width="modalWidth()"
    :visible="visible"
    :centered="true"
    @ok="handleSubmit"
    :bodyStyle="{height: modalHeight()}"
    @cancel="handleCancel">

    <div :style="modalStyle()">
      <a-spin :spinning="confirmLoading">
        <a-form :form="form">
          <a-form-item
            label="关系名称"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
            has-feedback
          >
            <a-select
              show-search
              :filter-option="searchOption"
              style="width: 98.2%"
              :getPopupContainer="
                triggerNode => {
                  return triggerNode.parentNode || document.body;
                }
              "
              placeholder="请输入关系名称"
              @change="relationChange"
              v-decorator="['relationId', {rules: [{ required: true, message: '请输入关系名称！' }]}]">
              <a-select-option v-for="(item,index) in relationList" :key="index" :value="item.id">{{ item.chName }}
              </a-select-option>
            </a-select>
          </a-form-item>
        </a-form>
        <a-button icon="plus" @click="addStrategy">添加策略</a-button>
        <a-form
          :form="strategyForms[index]"
          :key="index"
          v-for="(item,index) in strategyList"
          class="ant-advanced-search-form">
          <div style="margin-left: 2%;margin-bottom: 12px;color: red">策略名称: 策略{{ index + 1 }}</div>
          <a-row :gutter="24">
            <a-col :span="8">
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="策略类型">
                <a-select
                  @change="(v)=>strategyTypeChange(v,item,index)"
                  :getPopupContainer="
                    triggerNode => {
                      return triggerNode.parentNode || document.body;
                    }
                  "
                  v-decorator="['strategyType' , {initialValue: item.strategyType,rules: [{required: true, message: '请选择策略类型'}]}]">
                  <a-select-option value="完全相等">完全相等</a-select-option>
                  <a-select-option value="相似度">相似度</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="概念A">
                <a-input
                  v-model="item.conceptAName"
                  placeholder="请选择关系名称"
                  :disabled="true">
                </a-input>
              </a-form-item>
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="概念B">
                <a-input
                  placeholder="请选择关系名称"
                  v-model="item.conceptBName"
                  :disabled="true">
                </a-input>
              </a-form-item>
            </a-col>
            <a-col :span="8">
              <a-form-item
                v-if="item.strategyType !=='完全相等'"
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="相似度:">
                <a-input-number
                  @change="(v)=>item.similarity =v"
                  v-decorator="['similarity', {initialValue:item.similarity,rules: [{required: item.strategyType ==='相似度', message: '请输入相似度'}]}]"
                  :formatter="value => `${value}%`"
                  :parser="value => value.replace('%', '')"
                  :min="1"
                  :max="99"
                  style="width: 120px"></a-input-number>
              </a-form-item>
              <a-form-item
                v-else
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="">
                <div style="height: 40px"></div>
              </a-form-item>
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="属性:">
                <a-select
                  show-search
                  :getPopupContainer="
                    triggerNode => {
                      return triggerNode.parentNode || document.body;
                    }
                  "
                  :filter-option="searchOption"
                  placeholder="请选择属性"
                  @change="v=>item.propertyA =v"
                  v-decorator="['propertyA', {rules: [{ required: true, message: '请选择属性' }]}]">
                  <a-select-option v-for="(property,i) in propertyAList" :key="i" :value="property.id">
                    {{ property.chName }}
                  </a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="属性:">
                <a-select
                  show-search
                  :getPopupContainer="
                    triggerNode => {
                      return triggerNode.parentNode || document.body;
                    }
                  "
                  @change="v=>item.propertyB =v"
                  :filter-option="searchOption"
                  placeholder="请选择属性"
                  v-decorator="['propertyB', {rules: [{ required: true, message: '请选择属性' }]}]">
                  <a-select-option v-for="(property,i) in propertyBList" :key="i" :value="property.id">
                    {{ property.chName }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col :span="8">
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="">
                <div style="height: 40px"></div>
              </a-form-item>
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="规则: ">
                <a-popover
                  :visible="item.popoverAVisible"
                  placement="leftBottom"
                  :getPopupContainer="
                    triggerNode => {
                      return triggerNode.parentNode || document.body;
                    }
                  ">
                  <a-select
                    :default-value="item.propARuleType"
                    :getPopupContainer="
                      triggerNode => {
                        return triggerNode.parentNode || document.body;
                      }
                    ">
                    <a-select-option
                      @click="selectParseRule(type,item,1,index)"
                      v-for="type in parseRuleType"
                      :key="type"
                      :value="type">
                      {{ type }}
                    </a-select-option>
                  </a-select>
                  <template>
                    <div style="width: 320px;color: #333" slot="content">
                      <div>
                        <span>设置表达式</span>
                        <a-popconfirm
                          v-if="item.propertyARule"
                          placement="top"
                          title="确认删除？"
                          @confirm="() => delRuleConfig(item,1)">
                          <div
                            style="display: inline-block;float: right;color: red">
                            <a-icon type="delete"></a-icon>
                            <span>删除</span>
                          </div>
                        </a-popconfirm>
                      </div>
                      <div style="margin-top: 12px">
                        <a-textarea
                          placeholder="请输入表达式"
                          v-model="item.ruleAContent"
                          style="max-height: 320px"
                          :rows="6"></a-textarea>
                      </div>
                      <div style="margin-top: 12px">
                        <a-button @click="item.popoverAVisible =false">取消</a-button>
                        <a-button @click="ruleConfig(item,index,1)" style="margin-left: 12px">保存</a-button>
                      </div>
                    </div>
                  </template>
                </a-popover>
              </a-form-item>
              <a-form-item
                :labelCol="centerLabelCol"
                :wrapperCol="centerWrapperCol"
                label="规则: ">
                <a-popover
                  :visible="item.popoverBVisible"
                  placement="leftBottom"
                  :getPopupContainer="
                    triggerNode => {
                      return triggerNode.parentNode || document.body;
                    }
                  ">
                  <a-select
                    :defaultValue="item.propBRuleType"
                    :getPopupContainer="
                      triggerNode => {
                        return triggerNode.parentNode || document.body;
                      }
                    ">
                    <a-select-option
                      @click="selectParseRule(type,item,2,index)"
                      v-for="type in parseRuleType"
                      :key="type"
                      :value="type">
                      {{ type }}
                    </a-select-option>
                  </a-select>
                  <template>
                    <div style="width: 320px;color: #333" slot="content">
                      <div>
                        <span>设置表达式</span>
                        <a-popconfirm
                          v-if="item.propertyBRule"
                          placement="top"
                          title="确认删除？"
                          @confirm="() => delRuleConfig(item,2)">
                          <div
                            style="display: inline-block;float: right;color: red">
                            <a-icon type="delete"></a-icon>
                            <span>删除</span>
                          </div>
                        </a-popconfirm>
                      </div>
                      <div style="margin-top: 12px">
                        <a-textarea
                          placeholder="请输入表达式"
                          v-model="item.ruleBContent"
                          style="max-height: 320px"
                          :rows="6"></a-textarea>
                      </div>
                      <div style="margin-top: 12px">
                        <a-button @click="item.popoverBVisible =false">取消</a-button>
                        <a-button @click="ruleConfig(item,index,2)" style="margin-left: 12px">保存</a-button>
                      </div>
                    </div>
                  </template>
                </a-popover>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row>
            <a-button size="small" @click="removeStrategy(index)" class="rule_form_del">删除</a-button>
          </a-row>
        </a-form>
      </a-spin>
    </div>
  </a-modal>
</template>

<script>
import {
  relationList,
  relationRuleAdd,
  relationRuleEdit,
  relationRuleMerge
} from '@/api/modular/main/knowl/relation/relationManage'
import {
  addOrEditRuleConfig,
  deleteRuleConfig,
  propertyPage,
  propertyRuleConfigDetail
} from '@/api/modular/main/knowl/property/propertyManage'
import { register } from '@/utils/drag_modal'

export default {
  data() {
    return {
      title: undefined,
      currentRelation: undefined,
      updateId: undefined,
      strategyList: [],
      visible: false,
      confirmLoading: false,
      form: this.$form.createForm(this),
      strategyForms: [],
      relationList: [],
      propertyAList: [],
      propertyBList: [],
      parseRuleType: ['不解析', '表达式', '分词', '脚本'],
      labelCol: {
        xs: { span: 24 },
        sm: { span: 3 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 21 }
      },
      centerLabelCol: {
        xs: { span: 24 },
        sm: { span: 10 }
      },
      centerWrapperCol: {
        xs: { span: 24 },
        sm: { span: 14 }
      }
    }
  },
  methods: {
    strategyTypeChange(value, item, index) {
      item.strategyType = value
      if (value === '完全相等') {
        item.similarity = 100
      } else {
        item.similarity = undefined
      }
      this.strategyForms[index].setFieldsValue({
        similarity: item.similarity
      })
    },
    delRuleConfig(item, type) {
      this.confirmLoading = true
      const id = type === 1 ? item.propertyARule : item.propertyBRule
      deleteRuleConfig({
        id: id
      })
        .then((res) => {
          if (res.success) {
            this.$message.success('删除成功!')
            if (type === 1) {
              item.propertyARule = undefined
              item.ruleAContent = undefined
            } else {
              item.propertyBRule = undefined
              item.ruleBContent = undefined
            }
          } else {
            this.$message.error('删除失败!')
          }
        })
        .catch(() => {
          this.$message.error('删除失败!')
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },
    ruleAConfig(item, index) {
      this.confirmLoading = true
      addOrEditRuleConfig({
        id: item.ruleAExtroInfo && item.ruleAExtroInfo.type === item.propARuleType ? item.ruleAExtroInfo.id : undefined,
        type: item.propARuleType,
        content: item.ruleAContent
      })
        .then((res) => {
          const value = res.data
          if (value) {
            item.propertyARule = value.id
            item.ruleAExtroInfo = value
          }
          this.$message.success('保存成功!')
          item.popoverAVisible = false
        })
        .catch(() => {
          this.$message.error('保存失败!')
        })
        .finally(() => {
            this.confirmLoading = false
          }
        )
    },

    ruleBConfig(item, index) {
      this.confirmLoading = true
      addOrEditRuleConfig({
        id: item.ruleBExtroInfo && item.ruleBExtroInfo.type === item.propBRuleType ? item.ruleBExtroInfo.id : undefined,
        type: item.propBRuleType,
        content: item.ruleBContent
      })
        .then((res) => {
          const value = res.data
          if (value) {
            item.propertyBRule = value.id
            item.ruleBExtroInfo = value
          }
          this.$message.success('保存成功!')
          item.popoverBVisible = false
        })
        .catch(() => {
          this.$message.error('保存失败!')
        })
        .finally(() => {
            this.confirmLoading = false
          }
        )
    },
    ruleConfig(item, index, type) {
      if (type === 1) {
        this.ruleAConfig(item, index)
      } else {
        this.ruleBConfig(item, index)
      }
    },

    ruleAChange(v, item, index) {
      item.propARuleType = v
      if (v === '不解析') {
        item.popoverAVisible = false
      } else {
        const list = this.strategyList
        const max = list.length
        for (let i = 0; i < max; i++) {
          list[i].popoverBVisible = false
          list[i].popoverAVisible = i === index
        }
        if (item.propertyARule) {
          if (!item.ruleAExtroInfo) {
            this.confirmLoading = true
            propertyRuleConfigDetail({
              id: item.propertyARule
            })
              .then((res) => {
                if (res.success) {
                  const data = res.data
                  item.ruleAContent = data.type === v ? data.content : undefined
                } else {
                  this.$message.error('获取规则信息失败!')
                }
              })
              .catch(() => {
                this.$message.error('获取规则信息失败!')
              })
              .finally(() => {
                this.confirmLoading = false
              })
          } else {
            item.ruleAContent = item.ruleAExtroInfo.type === v ? item.ruleAExtroInfo.content : undefined
          }
        }
      }
    },
    ruleBChange(v, item, index) {
      item.propBRuleType = v
      if (v === '不解析') {
        item.popoverBVisible = false
      } else {
        const list = this.strategyList
        const max = list.length
        for (let i = 0; i < max; i++) {
          list[i].popoverAVisible = false
          list[i].popoverBVisible = i === index
        }
        if (item.propertyBRule) {
          if (!item.ruleBExtroInfo) {
            this.confirmLoading = true
            propertyRuleConfigDetail({
              id: item.propertyBRule
            })
              .then((res) => {
                if (res.success) {
                  const data = res.data
                  item.ruleBContent = data.type === v ? data.content : undefined
                } else {
                  this.$message.error('获取规则信息失败!')
                }
              })
              .catch(() => {
                this.$message.error('获取规则信息失败!')
              })
              .finally(() => {
                this.confirmLoading = false
              })
          } else {
            item.ruleBContent = item.ruleBExtroInfo.type === v ? item.ruleBExtroInfo.content : undefined
          }
        }
      }
    },
    selectParseRule(v, item, type, index) {
      if (type === 1) {
        this.ruleAChange(v, item, index)
      } else {
        this.ruleBChange(v, item, index)
      }
    },
    searchOption(input, option) {
      return (
        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
      )
    },
    fullStrategyName(i) {
      return '策略' + (i + 1)
    },
    removeStrategy(index) {
      this.strategyList.splice(index, 1)
      this.strategyForms.splice(index, 1)
    },
    addStrategy() {
      const lastForm = this.$form.createForm(this)
      const last = {
        strategyType: '相似度',
        popoverAVisible: false,
        popoverBVisible: false,
        propARuleType: '不解析',
        propBRuleType: '不解析',
        ruleAContent: '',
        ruleBContent: ''
      }
      this.strategyForms.push(lastForm)
      const relation = this.currentRelation
      if (relation) {
        last.conceptBName = relation.schemaToName
        last.conceptB = relation.schemaTo
        last.conceptAName = relation.schemaFromName
        last.conceptA = relation.schemaFrom
        this.strategyList.push(last)
      } else {
        this.strategyList.push(last)
      }
    },
    edit(item) {
      this.visible = true
      this.updateId = item.id
      this.title = '编辑解析规则'
      register(true)
      this.confirmLoading = true
      relationRuleMerge({}, { id: item.id })
        .then((res) => {
          this.fillValue(res)
        })
        .catch((e) => {
          console.log(e)
          this.$message.error('获取信息失败!')
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },
    add() {
      this.visible = true
      this.title = '添加解析规则'
      this.updateId = undefined
      register(true)
      this.confirmLoading = true
      relationList({})
        .then((data) => {
          this.relationList = data.data
        })
        .catch((e) => {
          console.log(e)
          this.$message.error('加载失败!')
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },

    loadProperty(schemaId, schemaType) {
      this.confirmLoading = true
      propertyPage({
        'schemaId': schemaId
      })
        .then((data) => {
          this.confirmLoading = false
          if (schemaType === 1) {
            this.propertyAList = data.data.rows
          } else {
            this.propertyBList = data.data.rows
          }
        })
        .catch(() => {
          this.confirmLoading = false
        })
    },

    relationChange(value) {
      const item = this.relationList.find((it) => it.id === value)
      this.currentRelation = item
      this.strategyList.forEach((it) => {
        it.conceptBName = item.schemaToName
        it.conceptB = item.schemaTo
        it.conceptAName = item.schemaFromName
        it.conceptA = item.schemaFrom
      })
      this.propertyAList = []
      this.propertyBList = []
      this.strategyForms.forEach(it => {
        it.setFieldsValue({
          propertyA: undefined,
          propertyB: undefined
        })
      })
      this.loadProperty(item.schemaFrom, 1)
      this.loadProperty(item.schemaTo, 2)
    },
    handleSubmit() {
      if (this.strategyList.length <= 0) {
        this.$message.error('策略信息不能为空!')
        return
      }
      const forms = []
      forms.push(this.form)
      const strategyForms = forms.concat(this.strategyForms)
      const errorList = []
      for (const form of strategyForms) {
        form.validateFields(err => {
          if (err) {
            errorList.push(true)
          }
        })
      }
      if (errorList.length <= 0) {
        const strategyList = []
        for (let i = 0; i < this.strategyForms.length; i++) {
          const form = this.strategyForms[i]
          const originEntity = this.strategyList[i]
          strategyList.push(Object.assign(form.getFieldsValue(), {
            name: '策略' + (i + 1),
            conceptA: originEntity.conceptA,
            conceptB: originEntity.conceptB,
            similarity: originEntity.similarity,
            propertyARule: originEntity.propARuleType === '不解析' ? undefined : originEntity.propertyARule,
            propertyBRule: originEntity.propBRuleType === '不解析' ? undefined : originEntity.propertyBRule,
            propARuleType: originEntity.propARuleType,
            propBRuleType: originEntity.propBRuleType
          }))
        }
        const relationId = this.form.getFieldsValue()['relationId']
        const relationName = this.relationList.find((it) => it.id === relationId).chName
        const parameter = {
          relationId: relationId,
          relationName: relationName,
          ruleType: '解析规则',
          id: this.updateId,
          strategyList: JSON.stringify(strategyList)
        }
        if (this.updateId) {
          this.updateRelationRule(parameter)
        } else {
          this.insertRelationRule(parameter)
        }
      }
    },
    updateRelationRule(parameter) {
      this.confirmLoading = true
      relationRuleEdit(parameter)
        .then((res) => {
          if (res.success) {
            this.$message.success('修改成功')
            this.$emit('ok')
            this.handleCancel()
          } else {
            this.$message.error('修改失败')
          }
        })
        .catch(() => {
          this.$message.error('修改失败')
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },
    insertRelationRule(parameter) {
      this.confirmLoading = true
      relationRuleAdd(parameter)
        .then((res) => {
          if (res.success) {
            this.$message.success('新增成功')
            this.$emit('ok')
            this.handleCancel()
          } else {
            this.$message.error('新增失败')
          }
        })
        .catch(() => {
          this.$message.error('新增失败')
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },
    modalWidth() {
      return document.body.clientWidth * 0.5
    },
    modalHeight() {
      return (document.body.clientHeight * 0.8) + 'px'
    },

    handleCancel() {
      this.visible = false
      this.form.resetFields()
      this.strategyForms = []
      register(false)
      this.strategyList = []
      this.currentRelation = undefined
      this.propertyAList = []
      this.propertyBList = []
    },
    modalStyle() {
      return {
        'overflow-y': 'overlay',
        'overflow-x': 'hidden',
        'height': '100%',
        'max-height': '100%',
        'padding-right': '9px'
      }
    },
    fillValue(res) {
      this.relationList = res.relation
      const detail = res.relationRule
      this.propertyAList = detail.propertyAList
      this.propertyBList = detail.propertyBList
      this.currentRelation = this.relationList.find((it) => it.id === detail.relationId)
      this.form.setFieldsValue({ relationId: detail.relationId })
      this.setStrategyList(detail)
    },
    setStrategyList(detail) {
      const strategys = JSON.parse(detail.strategyList)
      strategys.forEach((it) => {
        this.strategyList.push(Object.assign(it, {
          conceptAName: detail.conceptAName,
          conceptBName: detail.conceptBName,
          popoverAVisible: false,
          popoverBVisible: false,
          ruleAContent: '',
          ruleBContent: ''
        }))
        this.strategyForms.push(this.$form.createForm(this))
      })
      for (let i = 0; i < strategys.length; i++) {
        const form = this.strategyForms[i]
        const item = strategys[i]
        this.$nextTick(() => {
          form.setFieldsValue({
            strategyType: item.strategyType,
            propertyB: item.propertyB,
            propertyA: item.propertyA
          })
        })
      }
    }
  }
}
</script>

<style scoped>
.ant-advanced-search-form {
  border: 1px solid #d9d9d9;
  padding: 9px;
  margin-top: 10px;
  margin-right: 10px;
}

.ant-advanced-search-form .ant-form-item {
  display: flex;
}

::-webkit-scrollbar {
  width: 6px;
  background-color: rgba(240, 240, 240, 1);
}

.rule_form_del {
  float: right;
  margin-right: 0;
  margin-top: -12px;
  margin-bottom: 5px;
}
</style>
